import { to } from '@/tools'

export type RequestFn = (
  params?: any,
) => Promise<
  HttpResult.ResponseData<HttpResult.List | BusinessApi.CutPageResponse<any>>
>
export type TransformFn = (
  value: Record<string, any>,
  index?: number,
  array?: any,
) => Record<string, any>

interface params {
  request: RequestFn
  transform?: TransformFn
  size?: number
  openScrollToBottom?: boolean // 是否开启滚动到底部加载
  isInit?: boolean // 是否初始化加载
  awaitR?: boolean // 是否需要等待渲染时机
  isShow?: boolean // 是否显示
  afterFn?: () => void // 加载完成后的回调
}

type CallbackFn = ((
  value: any,
  index: number,
  array: any[],
) => Record<string, any>) &
((value: unknown, index: number, array: unknown[]) => Record<string, any>)

export const usePageList = ({
  request,
  transform,
  size,
  openScrollToBottom,
  isInit,
  awaitR,
  isShow,
  afterFn,
}: params) => {
  openScrollToBottom = openScrollToBottom ?? false;
  isInit = isInit ?? true;
  isShow = isShow ?? false;
  transform = (transform ?? (i => i)) as TransformFn;
  const state = reactive({
    list: [] as any[],
    totalCount: 0,
    loading: false,
    isNone: false,
    networkErr: false,
    pageNum: 0,
    pageSize: size || 10,
  });

  const query = async (params?: Record<string, any>) => {
    state.loading = true;
    const [err, res] = await to(
      request({
        ...params,
        pageNum: state.pageNum,
        pageSize: state.pageSize,
      }),
    );

    if (err || !res?.data) {
      uni.showToast({ title: '加载失败', icon: 'none' });
      state.networkErr = true;
      return (state.loading = false);
    }

    if (state.pageNum === 0) {
      state.list = (res.data.dataList! || []).map(transform as CallbackFn);
    }
    else {
      state.list = state.list.concat(
        (res.data.dataList! || []).map(transform as CallbackFn),
      );
    }

    if (
      state.pageNum === 0
      && (!res.data
        || (res.data && (!res.data.dataList?.length || res.data.totalCount === 0)))
    ) {
      state.isNone = true;
    }
    else {
      state.isNone = false;
    }

    state.totalCount = res.data.totalCount!;
    state.loading = false;

    afterFn?.();
  }

  const queryMore = async (params?: Record<string, any>) => {
    if (state.loading) {
      return;
    }
    if (state.list.length >= state.totalCount) {
      return;
    }
    state.pageNum++;
    await query(params);
  }

  const refresh = async (params?: Record<string, any>) => {
    state.pageNum = 0;
    await query(params);
  }

  const clearList = () => {
    state.list = [];
    state.totalCount = 0;
    state.pageNum = 0;
  }

  if (openScrollToBottom) {
    // 需要配合pages.json中的配置
    // 监听页面滚动到底部
    onReachBottom(queryMore);
  }

  // #ifndef MP-WEIXIN
  if (isInit) {
    onLoad(async () => {
      if (awaitR) {
        await nextTick();
      }
      query();
    })
  }
  // #endif
  // #ifdef MP-WEIXIN
  if (isInit) {
    onMounted(async () => {
      if (awaitR) {
        await nextTick();
      }
      query();
    })
  }
  // #endif

  if (isShow) {
    onShow(async () => {
      if (awaitR) {
        await nextTick();
      }
      query();
    })
  }

  return {
    state,
    query,
    queryMore,
    refresh,
    clearList,
  };
}
